#include <string.h>
#include "RC4Decode.h"
#include "MemAlloc.h"


#define SWAP(a, b)	do{unsigned char tmp = a; a = b; b = tmp;}while(0)

static void rc4_init(unsigned char *sbox, const unsigned char *key, unsigned int keylen)
{
	unsigned char j;
	unsigned int i;

	/* Initialize state with identity permutation */
	for (i = 0; i < 256; i++)
			sbox[i] = (unsigned char)i;

	/* Randomize the permutation using key data */
	for (j = i = 0; i < 256; i++) {
			j += sbox[i] + key[i % keylen];
			SWAP(sbox[i], sbox[j]);
	}
}

static void rc4_crypt(unsigned char *sbox, const unsigned char* inbuf, unsigned char* outbuf, unsigned int buflen)
{
	unsigned int i;
	unsigned char j, index1 = 0, index2 = 0;

	for (i = 0; i < buflen; i++) {

		/* Update modification indicies */
		index1++;
		index2 += sbox[index1];

		/* Modify permutation */
		SWAP(sbox[index1],
				sbox[index2]);

		/* Encrypt/decrypt next byte */
		j = sbox[index1] + sbox[index2];
		outbuf[i] = inbuf[i] ^ sbox[j];
	}
}


static unsigned char rc4Sbox[256];

void RC4_Setup(const unsigned char *key, unsigned int keylen){
	rc4_init(rc4Sbox, key, keylen);
}

void RC4_Crypt(const unsigned char* inbuf, unsigned char* outbuf, unsigned int buflen){
	rc4_crypt(rc4Sbox, inbuf, outbuf, buflen);
}


void RC4_Decode(const unsigned char* pwd, unsigned char pwd_len, 
	unsigned char* src, unsigned short len, unsigned char* out)
{
	rc4_init(rc4Sbox, pwd, pwd_len);
	rc4_crypt(rc4Sbox, src, out, len);
}


